package com.hung.triple.context;

import com.hung.triple.consumer.ConsumerBeanInfo;
import com.hung.triple.registry.ProviderBeanInfo;
import com.hung.triple.registry.Register;
import com.hung.triple.registry.RegisterFactory;
import com.hung.triple.transport.TransporterPool;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;
import java.util.Vector;

/**
 * 全局运行上下文 目前用来执行优雅退出销毁
 *
 * @author Hung
 * @date 2022/12/9 1:30
 */
@Slf4j
public class RpcRuntimeContext {

    /**
     * 发布的服务配置
     */
    private final static List<ProviderBeanInfo> EXPORTED_PROVIDER_CONFIGS = new Vector<>();

    /**
     * 发布的订阅配置
     */
    private final static List<ConsumerBeanInfo> REFERRED_CONSUMER_CONFIGS = new Vector<>();

    static {
        Runtime.getRuntime().addShutdownHook(new Thread(() -> {

            log.warn("RPC Framework catch JVM shutdown event, Run shutdown hook now.");

            destroy(false);

        }));
    }

    /**
     * 主动销毁全部SOFA RPC运行相关环境
     */
    public static void destroy() {
        destroy(true);
    }

    /**
     * 销毁方法
     *
     * @param active 是否主动销毁
     */
    private static void destroy(boolean active) {
        //TODO 可以做个 进入销毁状态的state 如果进入销毁状态，此时Consumer不再接收请求

        Register register = RegisterFactory.getRegister();

        //取消服务监听
        register.deSubscribe(REFERRED_CONSUMER_CONFIGS);

        //反注册Provider
        register.deRegister(EXPORTED_PROVIDER_CONFIGS);

        //关闭Transporter Channel
        TransporterPool.destroy();

        log.info("[Triple] RPC Framework has been release all resource {}...", active ? "actively" : "");
    }


    /**
     * 增加缓存ConsumerConfig
     *
     * @param consumerBeanInfo the consumer config
     */
    public static void cacheConsumerConfig(ConsumerBeanInfo consumerBeanInfo) {
        REFERRED_CONSUMER_CONFIGS.add(consumerBeanInfo);
    }

    /**
     * 缓存的ConsumerConfig失效
     *
     * @param consumerBeanInfo the consumer config
     */
    public static void invalidateConsumerConfig(ConsumerBeanInfo consumerBeanInfo) {
        REFERRED_CONSUMER_CONFIGS.remove(consumerBeanInfo);
    }

    /**
     * 增加缓存ProviderConfig
     *
     * @param providerBeanInfo the provider config
     */
    public static void cacheProviderConfig(ProviderBeanInfo providerBeanInfo) {
        EXPORTED_PROVIDER_CONFIGS.add(providerBeanInfo);
    }

    /**
     * 缓存的ProviderConfig失效
     *
     * @param providerBeanInfo the provider config
     */
    public static void invalidateProviderConfig(ProviderBeanInfo providerBeanInfo) {
        EXPORTED_PROVIDER_CONFIGS.remove(providerBeanInfo);
    }

    /**
     * 得到已发布的全部ProviderConfig
     *
     * @return the provider configs
     */
    public static List<ProviderBeanInfo> getProviderConfigs() {
        return new ArrayList<>(EXPORTED_PROVIDER_CONFIGS);
    }

    /**
     * 得到已调用的全部ConsumerConfig
     *
     * @return the consumer configs
     */
    public static List<ConsumerBeanInfo> getConsumerConfigs() {
        return new ArrayList<>(REFERRED_CONSUMER_CONFIGS);
    }

}
